/*
 * Copyright © 2004-2014 chenYuan. All rights reserved.
 * @Website:wwww.jspx.net
 * @Mail:39793751@qq.com
 * @author: chenYuan , 陈原
 * @License: Jspx.net Framework Code is open source (LGPL)，Jspx.net Framework 使用LGPL 开源授权协议发布。
 * @jvm:jdk1.6+  x86/amd64
 *
 */
package com.jspx.sober.dialect;

import com.jspx.sober.TableModels;
import com.jspx.utils.DateUtil;
import java.io.*;
import java.sql.*;
import java.util.Date;

/**
 * Created by IntelliJ IDEA.
 * User:chenYuan (mail:39793751@qq.com)
 * Date: 2007-1-31
 * Time: 0:34:39
 */
public class SmallDBDialect extends Dialect
{
    public SmallDBDialect()
    {

        standard_SQL.put(SQL_CREATE_TABLE, "CREATE TABLE ${" + KEY_TABLE_NAME + "} \n(\n" +
                " <#list column=" + KEY_COLUMN_LIST + ">${column},\n</#list>" +
                " \nPRIMARY KEY  (${" + KEY_PRIMARY_KEY + "})\n)");
        standard_SQL.put(SQL_CRITERIA_QUERY, "SELECT top ${" + SQL_RESULT_END_ROW + "} * FROM ${" + KEY_TABLE_NAME + "} <#if where=" + KEY_TERM + "!=''>WHERE ${" + KEY_TERM + "}</#if><#if where=" + KEY_FIELD_GROUPBY + "!=''> GROUP BY ${" + KEY_FIELD_GROUPBY + "}</#if><#if where=" + KEY_FIELD_ORDERBY + "!=''> ORDER BY ${" + KEY_FIELD_ORDERBY + "}</#if>");
        standard_SQL.put(String.class.getName(), "${" + COLUMN_NAME + "} <#if where=" + COLUMN_LENGTH + "&gt;255>text<#else>varchar(${" + COLUMN_LENGTH + "})</#else></#if> <#if where=" + COLUMN_NOT_NULL + ">NOT NULL</#if> default '${" + COLUMN_DEFAULT + "}'");
        standard_SQL.put(Boolean.class.getName(), "${" + COLUMN_NAME + "} smallint <#if where=" + COLUMN_NOT_NULL + ">NOT NULL</#if> default <#if where=" + COLUMN_DEFAULT + "==''>0<#else>${" + COLUMN_DEFAULT + "}</#else></#if>");
        standard_SQL.put(boolean.class.getName(), "${" + COLUMN_NAME + "} smallint <#if where=" + COLUMN_NOT_NULL + ">NOT NULL</#if> default <#if where=" + COLUMN_DEFAULT + "==''>0<#else>${" + COLUMN_DEFAULT + "}</#else></#if>");
        standard_SQL.put(Integer.class.getName(), "${" + COLUMN_NAME + "} <#if where=" + KEY_FIELD_SERIAL + ">COUNTER<#else>integer</#else></#if> <#if where=" + COLUMN_NOT_NULL + ">NOT NULL<#else> default <#if where=" + COLUMN_DEFAULT + "==''>'0'<#else>'${" + COLUMN_DEFAULT + "}'</#else></#if></#else></#if>");
        standard_SQL.put("int", "${" + COLUMN_NAME + "} <#if where=" + KEY_FIELD_SERIAL + ">COUNTER<#else>integer</#else></#if> <#if where=" + COLUMN_NOT_NULL + ">NOT NULL<#else> default <#if where=" + COLUMN_DEFAULT + "==''>'0'<#else>'${" + COLUMN_DEFAULT + "}'</#else></#if></#else></#if>");
        standard_SQL.put(Long.class.getName(), "${" + COLUMN_NAME + "} <#if where=" + KEY_FIELD_SERIAL + ">COUNTER<#else>bigint</#else></#if> <#if where=" + COLUMN_NOT_NULL + ">NOT NULL<#else>  default <#if where=" + COLUMN_DEFAULT + "==''>'0'<#else>'${" + COLUMN_DEFAULT + "}'</#else></#if></#else></#if>");
        standard_SQL.put("long", "${" + COLUMN_NAME + "} <#if where=" + KEY_FIELD_SERIAL + ">COUNTER<#else>bigint</#else></#if> <#if where=" + COLUMN_NOT_NULL + ">NOT NULL<#else>  default <#if where=" + COLUMN_DEFAULT + "==''>'0'<#else>'${" + COLUMN_DEFAULT + "}'</#else></#if></#else></#if>");
        standard_SQL.put(Double.class.getName(), "${" + COLUMN_NAME + "} double <#if where=" + COLUMN_NOT_NULL + ">NOT NULL</#if> default <#if where=" + COLUMN_DEFAULT + "==''>'0'<#else>'${" + COLUMN_DEFAULT + "}'</#else></#if>");
        standard_SQL.put("double", "${" + COLUMN_NAME + "} double <#if where=" + COLUMN_NOT_NULL + ">NOT NULL</#if> default <#if where=" + COLUMN_DEFAULT + "==''>'0'<#else>'${" + COLUMN_DEFAULT + "}'</#else></#if>");
        standard_SQL.put(Float.class.getName(), "${" + COLUMN_NAME + "} float <#if where=" + COLUMN_NOT_NULL + ">NOT NULL</#if> default <#if where=" + COLUMN_DEFAULT + "==''>'0'<#else>'${" + COLUMN_DEFAULT + "}'</#else></#if>");
        standard_SQL.put("float", "${" + COLUMN_NAME + "} float <#if where=" + COLUMN_NOT_NULL + ">NOT NULL</#if> default <#if where=" + COLUMN_DEFAULT + "==''>'0'<#else>'${" + COLUMN_DEFAULT + "}'</#else></#if>");
        standard_SQL.put(Date.class.getName(), "${" + COLUMN_NAME + "} datetime NOT NULL default now()");
        standard_SQL.put(byte[].class.getName(), "${" + COLUMN_NAME + "} LONGvarbinary");
        standard_SQL.put(InputStream.class.getName(), "${" + COLUMN_NAME + "} LONGvarbinary");
        standard_SQL.put(char.class.getName(), "${" + COLUMN_NAME + "} char(2) NOT NULL default ''");
        standard_SQL.put(SQL_DROP_TABLE, "DROP TABLE ${" + KEY_TABLE_NAME + "}");
        standard_SQL.put(FUN_TABLE_EXISTS, "exists table ${" + KEY_TABLE_NAME + "}");
    }

     /**
     * @param rs 数据对象
     * @param index  索引
     * @return 返回查询结果
     * @throws java.sql.SQLException
     */
    public Object getResultSetValue(ResultSet rs, int index) throws SQLException
    {
        String typeName = rs.getMetaData().getColumnTypeName(index);
        int colSize = rs.getMetaData().getColumnDisplaySize(index);

        //短断整型
        if ((typeName.equalsIgnoreCase("int") && colSize < 4) || typeName.equalsIgnoreCase("short") || typeName.equalsIgnoreCase("smallint") || typeName.equalsIgnoreCase("int2") || typeName.equalsIgnoreCase("tinyint") || (typeName.equalsIgnoreCase("fixed") && colSize < 4))
        {
            return rs.getShort(index);
        }
        //////////整型
        if (typeName.equalsIgnoreCase("int") || typeName.equalsIgnoreCase("integer") || typeName.equalsIgnoreCase("int4") || (typeName.equalsIgnoreCase("number") && colSize < 8) || (typeName.equalsIgnoreCase("fixed") && colSize < 19))
        {
            return rs.getInt(index);
        }

        ///////长整型
        if (typeName.equalsIgnoreCase("long") || typeName.equalsIgnoreCase("bigint") || typeName.equalsIgnoreCase("int8") || (typeName.equalsIgnoreCase("fixed") && colSize > 18))
        {
            return rs.getLong(index);
        }

        ///////单精度
        if (typeName.equalsIgnoreCase("money") || typeName.equalsIgnoreCase("float") || typeName.equalsIgnoreCase("real") || typeName.equalsIgnoreCase("binary_float"))
        {
            return rs.getFloat(index);
        }
        ///////大数值
        if (typeName.equalsIgnoreCase("decimal"))
        {
            return rs.getBigDecimal(index);
        }
        ///////双精度
        if (typeName.equalsIgnoreCase("double") || typeName.equalsIgnoreCase("double precision") || typeName.equalsIgnoreCase("binary_double"))
        {
            return rs.getDouble(index);
        }

  ///////日期
        if (typeName.equalsIgnoreCase("date")) {
            java.sql.Date t = rs.getDate(index);
            if (t == null) return DateUtil.empty;
            return new java.util.Date(t.getTime());
        }

        ///////日期时间
        if (typeName.equalsIgnoreCase("timestamp") || typeName.equalsIgnoreCase("datetime")) {
            Timestamp t = rs.getTimestamp(index);
            if (t == null) return DateUtil.empty;
            return new java.util.Date(t.getTime());
        }

        ////////////时间
        if (typeName.equalsIgnoreCase("time"))
        {
            return rs.getTime(index);
        }

        ///////短字符串
        if (typeName.equalsIgnoreCase("char") || typeName.equalsIgnoreCase("nvarchar") || typeName.equalsIgnoreCase("varchar") || typeName.equalsIgnoreCase("varchar2") || typeName.equalsIgnoreCase("tinyblob"))
        {
            return rs.getString(index);
        }

        ////////////大文本类型
        if (typeName.equalsIgnoreCase("CLOB") ||typeName.equalsIgnoreCase("mediumtext")  ||typeName.equalsIgnoreCase(" long varchar")
                || typeName.equalsIgnoreCase("ntext") || typeName.equalsIgnoreCase("text") || typeName.equalsIgnoreCase("long raw"))
        {
            Clob clob = rs.getClob(index);
            Reader bodyReader = clob.getCharacterStream();
            StringWriter out = new StringWriter(255);
            try
            {
                char buf[] = new char[256];
                int i;
                while ((i = bodyReader.read(buf)) != -1) out.write(buf, 0, i);
                out.close();
                bodyReader.close();
            } catch (Exception e)
            {
                e.printStackTrace();
            }
            return out.toString();
        }


        ///////二进制类型 文件类型
        if (typeName.equalsIgnoreCase("image") || typeName.equalsIgnoreCase("blob") || typeName.equalsIgnoreCase("LONGvarbinary")
                || typeName.equalsIgnoreCase("longblob") || typeName.equalsIgnoreCase("dbclob")
                ||typeName.equalsIgnoreCase("varbinary") || typeName.equalsIgnoreCase("binary") || typeName.equalsIgnoreCase("long byte"))
        {
            return new ByteArrayInputStream(rs.getBytes(index));
        }
        return rs.getObject(index);
    }



    public String getLimitString(String sql, int begin, int end, TableModels soberTable)
    {
        return sql;
    }

    public boolean supportsSequenceName()
    {
        return false;
    }

    public boolean supportsLimit()
    {
        return true;
    }

    public boolean supportsSavePoints()
    {
        return false;
    }

    public boolean supportsGetGeneratedKeys()
    {
        return false;
    }

    public boolean commentPatch()
    {
        return false;
    }
}